package com.apabi.aop;

import com.apabi.pojo.SysIpStats;
import com.apabi.service.SysIpService;
import com.apabi.service.SysIpStatsService;
import com.apabi.service.elastic.APICode;
import com.apabi.service.elastic.APIResult;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by atom on 18-1-17.
 */
public class TokenStatsAspect {

    private Logger logger = Logger.getLogger(TokenStatsAspect.class);

    @Autowired
    private SysIpService sysIpService;

    @Autowired
    private SysIpStatsService sysIpStatsService;

    private Object before(ProceedingJoinPoint point) {
        //获取request
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        // 获取请求ip
        String ip = request.getHeader("x-forwarded-for");
        // TODO: 可能存在 x-forwarded-for 中有多个ip的情况,但尚未见到这种情况,等验证后,再做处理
        if(ip ==null || ip.length() ==0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if(ip ==null || ip.length() ==0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ip ==null || ip.length() ==0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 获取请求的方法名
        String functionName = point.getSignature().getName();
        // 获取请求Header中的token
        String token = request.getHeader("token");

        if (!StringUtils.isEmpty(token)) {
            List<Map<String, String>> list = sysIpService.findLegalIpSegmentByToken(token);
            boolean status = false;
            String preIp;
            String endIp;
            for (Map<String, String> map : list) {
                preIp = map.get("pre_ip");
                endIp = map.get("end_ip");
                if(checkIpIsValid(preIp, endIp, ip)) {
                    status = true;
                    break;
                }
            }
            if (status) {
                SysIpStats sysIpStats = new SysIpStats();
                sysIpStats.setToken(token);
                sysIpStats.setIp(ip);
                sysIpStats.setApi(functionName);
                sysIpStats.setCreateTime(new Date());
                // 记录插入数据库 且 放行
                sysIpStatsService.saveSysIpStats(sysIpStats);
                try {
                    return point.proceed();
                } catch (Throwable throwable) {
                    logger.error("权限切面错误: " + throwable.getMessage());
                    return new APIResult<>(APICode.SYS_EXCEPTION);
                }
            } else if (status == false && list.size() > 0) {
                // 中断请求
                return new APIResult<>(APICode.IP_NOT_WHITELIST);
            } else {
                // 中断请求
                return new APIResult<>(APICode.AUTH_KEY_ERROR);
            }
        } else {
            // 中断请求
            return new APIResult<>(APICode.AUTH_KEY_ERROR);
        }
    }

    // 校验ip是否在ip段内
    private boolean checkIpIsValid(String preIp, String endIp, String ip) {
        String[] sips = preIp.split("\\.");
        String[] sipe = endIp.split("\\.");
        String[] sipt = ip.split("\\.");
        long ips = 0L, ipe = 0L, ipt = 0L;
        for (int i = 0; i < 4; ++i) {
            ips = ips << 8 | Integer.parseInt(sips[i]);
            ipe = ipe << 8 | Integer.parseInt(sipe[i]);
            ipt = ipt << 8 | Integer.parseInt(sipt[i]);
        }
        if (ips > ipe) {
            long t = ips;
            ips = ipe;
            ipe = t;
        }
        return ips <= ipt && ipt <= ipe;
    }
}
